    /*  
    championBuilder - Champions Online character planner.
    Copyright (C) 2009 Moritz Hartmeier
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You can find the GNU General Public License in the data folder.
    */


package ch.zarzu.champions.builder.gui;

import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.HashMap;

import javax.swing.*;

import org.w3c.dom.*;

import ch.zarzu.champions.builder.SystemLink;
import ch.zarzu.champions.builder.data.PowerData;
import ch.zarzu.champions.builder.logic.*;
import ch.zarzu.util.*;

public class BuildPower extends JLayeredPane implements MouseListener {
    private BuildUpdater updater;
    private JButton button, image, lock, activated_button;
    private AdvantageBubbles advantage_frame;
    private JLabel label;
    private Node slot;
    private NamedNodeMap attributes;
    private boolean is_active, is_erroneous, is_power_activated;
    private PowerData power;
    private String type, app_path;
    private SpringLayout layout;
    private LinkedList<PowerData> advantage_list;
    private Listener listener;
    private TitlePhrase name;
    
    public BuildPower(Node xml_slot, String t) {
        power = null;
        slot = xml_slot;
        updater = BuildUpdater.getInstance();
        listener = Listener.getInstance();
        attributes = xml_slot.getAttributes();
        type = t;
        
        app_path = AppPath.get();
        
        layout = new SpringLayout();
        setLayout(layout);
        
        draw();

        setActive(false);
        setErroneous(false);
        setPowerActivated(false);
        advantage_list = new LinkedList<PowerData>();
    }
    
    public void draw() {
        SystemLink sys_link = SystemLink.getInstance();
        String label_text = sys_link.translate("level") + " " + attributes.getNamedItem("level").getNodeValue();
        if(attributes.getNamedItem("type").getNodeValue().contains("travel")){
            label_text += " (" + sys_link.translate("travel") + ")";
        } else if(attributes.getNamedItem("type").getNodeValue().contains("innate")) {
            label_text += " (" + sys_link.translate("innate") + ")";
        }
        label = new JLabel(label_text);
        label.setForeground(Color.WHITE);
        label.setBackground(new Color(12, 128, 215));
        label.setFont(new Font("Comic Sans MS", Font.BOLD, 11));
        
        ImageIcon icon = new ImageIcon(app_path + "images/misc/lock.png");
        lock = new JButton(icon);
        lock.setBorder(null);
        lock.setFocusable(false);
        lock.setContentAreaFilled(false);
        lock.addMouseListener(this);
        lock.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
        lock.setVisible(false);
        
        icon = new ImageIcon(app_path + "images/misc/active_a.png");
        activated_button = new JButton(icon);
        activated_button.setBorder(null);
        activated_button.setFocusable(false);
        activated_button.setContentAreaFilled(false);
        activated_button.addMouseListener(this);
        activated_button.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
        activated_button.setVisible(getType().contains("power"));
        
        icon = new ImageIcon(app_path + "images/empty_a.png");
        button = new JButton(icon);
        button.setBorder(null);
        button.setFocusable(false);
        button.setContentAreaFilled(false);
        button.setPreferredSize(new Dimension(icon.getIconWidth() + 4, icon.getIconHeight()));
        button.addMouseListener(this);
        
        image = new JButton();
        image.setBorder(null);
        image.setFocusable(false);
        image.setContentAreaFilled(false);
        //image.setBackground(new Color(12, 128, 215));
        image.setVisible(false);
        image.addMouseListener(this);
        
        name = new TitlePhrase("",123);

        if(type.equals("power"))
            advantage_frame = new AdvantageBubbles(this, button.getIcon().getIconWidth());
        
        redraw();
    }
    
    private void redraw() {
        removeAll();
        
        if(isActive()) {
            button.setIcon(new ImageIcon(app_path + "images/empty_b.png"));
            if(power != null) {
                ImageIcon icon = new ImageIcon(power.getPath() + "b.jpg");
                image.setIcon(icon);
                image.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
            } else {
                image.setIcon(null);
            }
        } else {
            button.setIcon(new ImageIcon(app_path + "images/empty_a.png"));
            if(power != null) {
                ImageIcon icon = new ImageIcon(power.getPath() + "a.jpg");
                image.setIcon(icon);
                image.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
            } else {
                image.setIcon(null);
            }
        }
        
        add(label);
        add(lock);
        add(activated_button);
        
        layout.putConstraint(SpringLayout.WEST, label, 20, SpringLayout.WEST, button);
        layout.putConstraint(SpringLayout.WEST, name, 40, SpringLayout.WEST, this);
        layout.putConstraint(SpringLayout.NORTH, name, 3, SpringLayout.SOUTH, label);
        layout.putConstraint(SpringLayout.WEST, button, 0, SpringLayout.WEST, this);
        layout.putConstraint(SpringLayout.NORTH, button, 0, SpringLayout.SOUTH, label);
        layout.putConstraint(SpringLayout.WEST, image, 5, SpringLayout.WEST, this);
        layout.putConstraint(SpringLayout.NORTH, image, 3, SpringLayout.SOUTH, label);
        layout.putConstraint(SpringLayout.EAST, this, 0, SpringLayout.EAST, button);
        layout.putConstraint(SpringLayout.SOUTH, this, 0, SpringLayout.SOUTH, button);
        layout.putConstraint(SpringLayout.EAST, lock, -2, SpringLayout.EAST, this);
        layout.putConstraint(SpringLayout.NORTH, lock, -2, SpringLayout.NORTH, button);
        layout.putConstraint(SpringLayout.NORTH, activated_button, 14, SpringLayout.NORTH, this);
        
        if(type.equals("power")) {
            add(advantage_frame);

            layout.putConstraint(SpringLayout.EAST, advantage_frame, 0, SpringLayout.EAST, button);
            layout.putConstraint(SpringLayout.NORTH, advantage_frame, -6, SpringLayout.SOUTH, button);
            layout.putConstraint(SpringLayout.SOUTH, this, 0, SpringLayout.SOUTH, advantage_frame);
        }

        add(name);
        add(image);
        add(button);
    }
    
    public void setPower(PowerData new_power) {
        clearAdvantages();
        power = new_power;
        power.setUsed(true);
        setPowerActivated(!getType().contains("power"));
        name = new TitlePhrase(power.getName(), 123);
        setActive(isActive());
        image.setVisible(true);
    }
    
    public void removePower() {
        clearAdvantages();
        power.setUsed(false);
        power = null;
        setPowerActivated(false);
        setLockVisible(false);

        name = new TitlePhrase("");
        setActive(isActive());
        
        image.setVisible(false);
    }
    
    public void addAdvantage(PowerData advantage) {
        advantage_list.add(advantage);
        advantage.setUsed(true);
        updateBubbles();
    }
    
    public void removeAdvantage(PowerData advantage) {
        advantage_list.remove(advantage);
        advantage.setUsed(false);
        updateBubbles();
    }
    
    public boolean containsAdvantage(PowerData advantage) {
        return advantage_list.contains(advantage);
    }
    
    public LinkedList<PowerData> getAdvantages() {
        return advantage_list;
    }
    
    public void clearAdvantages() {
        for(PowerData a : advantage_list) {
            a.setUsed(false);
        }
        if(getType().contains("power")) {
            advantage_list.clear();
            updateBubbles();
        }
    }
    
    private void updateBubbles() {
        int cost = 0;
        for(PowerData a : advantage_list) {
            cost += a.getCost();
        }
        advantage_frame.setActive(cost);
    }
    
    public boolean canTakeAdvantage(PowerData advantage) {
        int cost = 0;
        
        String requirements = advantage.getRequirements();
        for(PowerData a : advantage_list) {
            if(!a.getId().equals(advantage.getId())) {
                cost += a.getCost();
                //remove all the ids of the advantages this power carries from the requirements, use only the advantage id for this, not the unique power id + advantage id
                requirements = requirements.replace(a.getId().substring(4), "");
            }
        }
        if(cost + advantage.getCost() <= 5 && requirements.equals(""))
            return true;
        else
            return false;
    }
    
    public boolean isPowerEqual(PowerData other_power) {
        
        if(power != null) {
            return other_power.getId().equals(getId());
        } else
            return false;
    }
    
    public String getType() {
        return slot.getAttributes().getNamedItem("type").getNodeValue();
    }
    
    public int getLevel() {
        return Integer.parseInt(slot.getAttributes().getNamedItem("level").getNodeValue());
    }
    
    //returns the id of the slotted power, returns zzzz if none is slotted
    public String getId() {
        if(power != null) {
            return power.getId();
        } else {
            return "zzzz";
        }
    }
    
    public boolean isEmpty() {
        return getId().equals("zzzz");
    }
    
    //returns the name of the slotted power, else ""
    public String getName() {
        if(power != null) {
            return power.getName();
        } else {
            return "";
        }
    }
    
    public LinkedList<LinkedList<HashMap<String, String>>> getEffects() {
        if(power != null)
            return power.getEffects();
        else
            return null;
    }
    
    public void mouseEntered(MouseEvent e) {
        if(power != null)
            listener.powerMouseOver(getId());
    }
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {
        if(getType().contains("power") && advantage_frame.bubbles.contains(e.getSource())) {
            listener.buildPowerClick(this);
            if(power != null)
                listener.bubblesClick(this);
        } else if(getType().contains("power") && e.getSource() == activated_button) {
            if(power != null) {
                listener.buildPowerActivated(this);
            }
        } else if(e.getButton() == MouseEvent.BUTTON1 && e.getSource() != lock) {
            if(e.getClickCount() == 1)
                listener.buildPowerClick(this);
            else
                listener.buildPowerSwitchPool(this);
        
        } else if(e.getButton() == MouseEvent.BUTTON3 || e.getSource() == lock) {
            if(power != null)
                listener.powerLock(getId());
        }
    }
    
    public void setErroneous(boolean erroneous) {
        if(erroneous) {
            label.setForeground(Color.RED);
        } else {
            label.setForeground(Color.WHITE);
        }
        
        is_erroneous = erroneous;
    }
    
    public boolean isErroneous() {
        return is_erroneous;
    }
    
    //set slot to active
    public void setActive(boolean active) {
        
        is_active = active;
        redraw();
    }
    
    public void setPowerActivated(boolean activated) {
        if(activated) {
            ImageIcon icon = new ImageIcon(app_path + "images/misc/active_b.png");
            activated_button.setIcon(icon);
        } else {
            ImageIcon icon = new ImageIcon(app_path + "images/misc/active_a.png");
            activated_button.setIcon(icon);
        }
        is_power_activated = activated;
        updater.updateCharacteristics();
    }
    
    //sets the visibility of the lock
    public void setLockVisible(boolean b) {
        lock.setVisible(b);
    }
    
    //is the slot active?
    public boolean isActive() {
        return is_active;
    }
    
    public boolean isPowerActivated() {
        return is_power_activated;
    }
}
